/*
 * Class: SGettor
 * 
 * Created on Sep 27, 2013
 * 
 * (c) Copyright by Minh Tran
 * Global Cybersoft VN.
 * Floor 3-4-5, Helios Building, Quang Trung Software City
 */
package com.minh.tran.sg.view;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.xml.DOMConfigurator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;

import swing2swt.layout.BorderLayout;

import com.minh.tran.sg.Configuration;
import com.minh.tran.sg.Constant;
import com.minh.tran.sg.Gettor;
import com.minh.tran.sg.PlaylistGenerator;
import com.minh.tran.sg.model.ISItem;
import com.minh.tran.sg.model.Song;

/**
 * The Class SGettor.
 */
public class SGettor
{

    /** The Constant LOG. */
    private static final Log LOG = LogFactory.getLog(SGettor.class);

    /** The Constant MSG_SUCCESS. */
    protected static final int MSG_SUCCESS = 3;

    /** The Constant MSG_FAIL. */
    protected static final int MSG_FAIL = 2;

    /** The Constant MSG_NORMAL. */
    protected static final int MSG_NORMAL = 1;

    /** The shell. */
    protected Shell shell;

    /** The txt song url. */
    private Text txtSongUrl;

    /** The tbl songs. */
    private Table tblSongs;

    /** The display. */
    private final Display display = Display.getDefault();

    /** The configuration. */
    private final Configuration configuration = new Configuration();

    /** The list songs. */
    private final List<Song> lstSongs = new ArrayList<Song>();

    /** The lbl information. */
    private Label lblInformation;

    /** The is finding. */
    protected boolean isFinding;

    /**
     * Launch the application.
     *
     * @param args the arguments
     */
    public static void main(String[] args)
    {
        DOMConfigurator.configure("log4j.xml");
        try
        {
            SGettor window = new SGettor();
            window.open();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * Open the window.
     */
    public void open()
    {

        this.createContents();
        this.shell.open();
        this.shell.layout();
        while (!this.shell.isDisposed())
        {
            if (!this.display.readAndDispatch())
            {
                this.display.sleep();
            }
        }
    }

    /**
     * Create contents of the window.
     */
    protected void createContents()
    {
        this.shell = new Shell();
        this.shell.setImage(SWTResourceManager
            .getImage("F:\\PICTURE\\Emoticons\\IconsLandVistaStyleEmoticonsDemo\\ICO\\Study.ico"));
        this.shell.setSize(850, 600);
        this.shell.setText("NCT Gettor");
        this.shell.setLayout(new FillLayout(SWT.HORIZONTAL));

        Composite comParent = new Composite(this.shell, SWT.NONE);
        comParent.setLayout(new BorderLayout(0, 0));

        Composite comInput = new Composite(comParent, SWT.NONE);
        comInput.setLayoutData(BorderLayout.NORTH);
        comInput.setLayout(new GridLayout(2, false));

        Label lblUrl = new Label(comInput, SWT.NONE);
        lblUrl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblUrl.setText("URL");

        this.txtSongUrl = new Text(comInput, SWT.BORDER);
        this.txtSongUrl.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseUp(MouseEvent e)
            {
                SGettor.this.txtSongUrl.selectAll();
            }
        });
        this.txtSongUrl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        new Label(comInput, SWT.NONE);

        Group grpAction = new Group(comInput, SWT.NONE);
        grpAction.setLayout(new GridLayout(20, false));
        grpAction.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
        grpAction.setText("Action");

        Button btnFind = new Button(grpAction, SWT.NONE);
        btnFind.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent e)
            {
                String linkText = SGettor.this.txtSongUrl.getText();
                SGettor.this.findMP3link(linkText);
            }
        });
        btnFind.setText("Find");

        Button btnSaveAsWpl = new Button(grpAction, SWT.NONE);
        btnSaveAsWpl.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent e)
            {
                FileDialog fDialog = new FileDialog(SGettor.this.shell, SWT.SAVE);
                fDialog.setFilterExtensions(Constant.FILE_FILTER);
                if (null != fDialog.open())
                {
                    String fileName = fDialog.getFileName();
                    String path = fDialog.getFilterPath() + File.separator + fileName;
                    if (SGettor.this.lstSongs.size() > 0 && path != null)
                    {
                        String title = fileName.substring(0, fileName.lastIndexOf(Constant.CHAR_DOT));
                        PlaylistGenerator gener = new PlaylistGenerator(title, SGettor.this.lstSongs);
                        if (gener.generate(path))
                        {
                            SGettor.this.message("Saved successfully!", MSG_SUCCESS);
                        }
                        else
                        {
                            SGettor.this.message("Failed to save file!", MSG_FAIL);
                        }
                    }
                }
            }
        });
        btnSaveAsWpl.setText("Save as Wpl");
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);
        new Label(grpAction, SWT.NONE);

        this.lblInformation = new Label(grpAction, SWT.NONE);
        this.lblInformation.setAlignment(SWT.RIGHT);
        this.lblInformation.setFont(SWTResourceManager.getFont("Segoe UI", 9, SWT.ITALIC));
        this.lblInformation.setText("information");
        this.lblInformation.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, true, false, 6, 1));

        Composite comResult = new Composite(comParent, SWT.NONE);
        comResult.setLayoutData(BorderLayout.CENTER);
        comResult.setLayout(new FillLayout(SWT.HORIZONTAL));

        this.tblSongs = new Table(comResult, SWT.BORDER | SWT.FULL_SELECTION);
        this.tblSongs.setHeaderVisible(true);
        this.tblSongs.setLinesVisible(true);
        this.initColums();
        Menu menu = new Menu(this.shell, SWT.BAR);
        this.shell.setMenuBar(menu);

        MenuItem mntmEdit = new MenuItem(menu, SWT.CASCADE);
        mntmEdit.setText("Edit");

        Menu subMnConfig = new Menu(mntmEdit);
        mntmEdit.setMenu(subMnConfig);

        MenuItem mntmConfig = new MenuItem(subMnConfig, SWT.NONE);
        mntmConfig.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent e)
            {
                try
                {
                    Login loginView = new Login(SGettor.this.configuration);
                    loginView.open();
                }
                catch (Exception e1)
                {
                    e1.printStackTrace();
                }
            }
        });
        mntmConfig.setText("Config");
    }

    /**
     * Message.
     *
     * @param msg the string
     * @param msgLevel the msg success
     */
    private void message(final String msg, final int msgLevel)
    {
        this.lblInformation.setText(msg);
        Color color = new Color(this.display, 0, 0, 0);
        if (msgLevel > 0)
        {
            switch (msgLevel)
            {
            case MSG_FAIL:
                color = new Color(this.display, 255, 0, 0);
                break;
            case MSG_NORMAL:
                color = new Color(this.display, 0, 0, 0);
                break;
            case MSG_SUCCESS:
                color = new Color(this.display, 20, 20, 250);
                break;
            default:
                break;
            }
        }
        this.lblInformation.setForeground(color);
        this.lblInformation.redraw();
    }

    /**
     * Inits the colums.
     */
    private void initColums()
    {
        TableColumn[] columns = new TableColumn[Constant.COLUMNS.length];
        for (int i = 0, n = columns.length; i < n; i++)
        {
            columns[i] = new TableColumn(this.tblSongs, SWT.LEFT);
            columns[i].setText(Constant.COLUMNS[i]);
            columns[i].setWidth(Constant.COL_WIDTH);
            columns[i].pack();
        }
    }

    /**
     * Fill table.
     *
     */
    private void fillTable()
    {
        this.tblSongs.setRedraw(false);
        for (Iterator<Song> iterator = this.lstSongs.iterator(); iterator.hasNext();)
        {
            Song player = iterator.next();
            LOG.info(player.toString());
            TableItem item = new TableItem(this.tblSongs, SWT.NONE);
            int c = 0;
            item.setText(c++, player.getTitle());
            item.setText(c++, player.getSinger());
            item.setText(c++, player.getLocation());
            item.setText(c++, player.getInfo());
            item.setText(c++, player.getImage());
        }
        this.tblSongs.setRedraw(true);
        if (this.tblSongs.getItemCount() > 0)
        {
            this.message("Found " + this.tblSongs.getItemCount() + " songs", MSG_SUCCESS);
        }
    }

    /**
     * Fill.
     */
    public void fill()
    {
        this.isFinding = false;
        this.display.asyncExec(new Runnable()
        {

            @Override
            public void run()
            {
                SGettor.this.fillTable();
                SGettor.this.refreshTable();
            }
        });

    }

    /**
     * Refresh table.
     */
    protected void refreshTable()
    {
        for (TableColumn col : this.tblSongs.getColumns())
        {
            col.pack();
        }
    }

    /**
     * Find m p3link.
     *
     * @param songLink the song link
     */
    protected void findMP3link(final String songLink)
    {
        if (!this.lstSongs.isEmpty())
        {
            this.lstSongs.clear();
        }
        LOG.info("Begin finding...");
        ISItem song = new Song(songLink);
        System.out.println(song.isASong() + "|" + song.isPlaylist());
        if (!song.isASong() && !song.isPlaylist())
        {
            this.cantGetConnectionToLink(songLink);
            return;
        }
        this.isFinding = true;
        this.getConnection();
        Gettor gettor = new Gettor(this, song, this.lstSongs, this.configuration);
        gettor.startProcess();
        LOG.info("End finding!");
    }

    /**
     * Gets the connection.
     *
     * @return the connection
     */
    private void getConnection()
    {
        this.message("Finding  .  .  .", MSG_NORMAL);
        this.clearTable();
    }

    /**
     * Cant get connection to link.
     *
     * @param info the info
     */
    public void cantGetConnectionToLink(final String info)
    {
        this.message("Can't connect to the link!", MSG_FAIL);
        if (!this.lstSongs.isEmpty())
        {
            this.lstSongs.clear();
        }
        this.clearTable();
    }

    /**
     * Clear table.
     */
    private void clearTable()
    {
        this.tblSongs.clearAll();
        this.tblSongs.setItemCount(0);
    }
}
